package com.LachesismStorm.lachesism.member.service.impl;

import com.LachesismStorm.lachesism.core.common.response.ResponsePage;
import com.LachesismStorm.lachesism.core.service.RedisService;
import com.LachesismStorm.lachesism.member.mapper.DatingMapper;
import com.LachesismStorm.lachesism.member.mapper.UmsUserMapper;
import com.LachesismStorm.lachesism.member.service.DatingService;
import com.LachesismStorm.lachesism.member.util.MemberUtil;
import com.LachesismStorm.lachesism.member.vo.*;
import com.LachesismStorm.lachesism.member.vo.dto.*;
import com.LachesismStorm.lachesism.member.vo.dto.SysArea;
import com.LachesismStorm.lachesism.member.vo.param.DatingEventParam;
import com.LachesismStorm.lachesism.member.vo.param.DatingForumParam;
import com.LachesismStorm.lachesism.member.vo.param.MemberParam;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.LachesismStorm.lachesism.member.websocket.WebSocketService.notification;

/**
 * @Author lachesism
 * @Date 2025-02-24 13:50
 **/
@Service
public class DatingServiceImpl implements DatingService {

    @Resource
    private DatingMapper datingMapper;
    @Resource
    private UmsUserMapper userMapper;
    @Resource
    private RedisService redisService;

    private static Set<String> swearWordsSet = new HashSet<>();

    @PostConstruct
    public void initSwearWords() {
        loadSwearWords();
    }

    @Scheduled(fixedRate = 3600000) // 每小时执行一次，单位是毫秒（3600000ms = 1小时）
    public void updateSwearWords() {
        loadSwearWords();
    }

    private void loadSwearWords() {
        System.out.println("开始初始化脏话列表");
        List<String> swearWords = userMapper.getSwearing(); // 从数据库获取脏话列表
        swearWordsSet.clear(); // 清空现有的脏话列表
        swearWordsSet.addAll(swearWords); // 添加新的脏话列表
        System.out.println("脏话列表已初始化，包含" + swearWordsSet.size() + "个脏话");
    }

    @Override
    public List<AreaList> geAllArea() {
        List<AreaList> AreaCache = (List<AreaList>) redisService.getWithTimeout("Area");
        if (AreaCache != null) {
            return AreaCache;
        }
        // 查询所有区域信息
        List<SysArea> areas = datingMapper.getAreaList();

        // 防止 areas 为 null
        if (areas == null || areas.isEmpty()) {
            return new ArrayList<>(); // 返回空列表
        }

        // 创建一个 map 存储父子关系
        Map<Integer, SysArea> areaMap = new HashMap<>();
        for (SysArea area : areas) {
            areaMap.put(area.getDistrictId(), area);
        }
        // 构建父子级关系
        for (SysArea area : areas) {
            if (area.getParentId() != null) {
                SysArea parentArea = areaMap.get(area.getParentId());
                if (parentArea != null) {
                    // 确保父区域的 sonList 已初始化
                    if (parentArea.getSonList() == null) {
                        parentArea.setSonList(new ArrayList<>());
                    }
                    parentArea.getSonList().add(area); // 将当前区域作为子区域加入父区域的 sonList 中
                }
            }
        }
        // 构建 AreaList
        List<AreaList> areaLists = new ArrayList<>();
        for (SysArea area : areas) {
            if (area.getLevelType() == 1) {  // 如果是省级区域（没有父级区域）
                AreaList areaList = new AreaList();
                areaList.setProvince(area.getName()); // 省级区域的 name 设置为 province
                List<String> cities = new ArrayList<>();
                // 遍历该省的子区域
                if (area.getSonList() != null) {  // 确保 sonList 不为 null
                    for (SysArea cityArea : area.getSonList()) {
                        cities.add(cityArea.getName()); // 将子区域的 name 加入 city 列表
                    }
                }
                areaList.setCity(cities);
                areaLists.add(areaList); // 添加到返回的列表中
            }
        }
        redisService.set("Area", areaLists);
        // 返回 areaLists 作为最终结果
        return areaLists;
    }

    @Override
    public ResponsePage<MemberDto> getUserList(MemberParam umsMemberParam) {
        PageHelper.startPage(umsMemberParam.getPageNum(), umsMemberParam.getPageSize());
        List<MemberDto> memberList = datingMapper.getUserList(umsMemberParam);
        return ResponsePage.restPage(new PageInfo<>(memberList));
    }

    @Override
    public void sendMessage(String message, Integer userId) {
        UmsMember userInfo = userMapper.getUserInfo(userId);
        userInfo.setHabits(message);
        datingMapper.sendMessage(userInfo);
    }

    @Override
    public List<String> getSwearing() {
        return userMapper.getSwearing();
    }

    @Override
    public ResponsePage<DatingChat> getChatList(MemberParam memberParam) {
        PageHelper.startPage(memberParam.getPageNum(), memberParam.getPageSize());
        List<DatingChat> chatList = datingMapper.getChatList();
        return ResponsePage.restPage(new PageInfo<>(chatList));
    }

    @Override
    public void createEvent(DatingEvent datingEvent) {
        UmsMember userInfo = MemberUtil.getUserInfo();
        datingEvent.setUserId(userInfo.getId());
        datingEvent.setUserName(userInfo.getNickName());
        if (datingEvent.getContact() == null) {
            datingEvent.setContact(userInfo.getPhone());
        }
        datingMapper.createEvent(datingEvent);
    }

    public void addApplicationCount(Integer id) {
        datingMapper.addApplicationCount(id);
    }

    @Override
    public ResponsePage<DatingEvent> getDatEventList(DatingEventParam datingEvent) {
        PageHelper.startPage(datingEvent.getPageNum(), datingEvent.getPageSize());
        List<DatingEvent> events = datingMapper.getDatEventList();
        return ResponsePage.restPage(new PageInfo<>(events));

    }

    @Override
    public void updateEvent(DatingEvent datingEvent) {
        datingMapper.updateEvent(datingEvent);
    }

    @Override
    public void eventApplication(DatingEventApplication application) {
        UmsMember userInfo = MemberUtil.getUserInfo();
        application.setUserId(userInfo.getId());
        application.setUserName(userInfo.getNickName());
        datingMapper.eventApplication(application);
    }

    @Override
    public List<DatingEventApplication> getEventApplicationList(DatingEvent application) {
        return datingMapper.getEventApplicationList(application.getId());
    }

    @Override
    public ResponsePage<DatingEventDto> getMyEventApplicationList(DatingEventParam datingEvent) {
        PageHelper.startPage(datingEvent.getPageNum(), datingEvent.getPageSize());
        List<DatingEventDto> events = datingMapper.getMyEventApplicationList(MemberUtil.getUserId());
        return ResponsePage.restPage(new PageInfo<>(events));
    }

    @Override
    public void publishForum(DatingForum forum) {
        UmsMember userInfo = MemberUtil.getUserInfo();
        forum.setUserId(userInfo.getId());
        forum.setUsername(userInfo.getNickName());
        forum.setAvatar(userInfo.getIcon());
        datingMapper.publishForum(forum);

    }

    @Override
    public ResponsePage<DatingForum> getForumList(DatingForumParam forum) {
        PageHelper.startPage(forum.getPageNum(), forum.getPageSize());
        List<DatingForum> memberList = datingMapper.getForumList(forum);
        return ResponsePage.restPage(new PageInfo<>(memberList));

    }

    @Override
    public ResponsePage<DatingForum> getMyForumList(DatingForumParam forum) {
        PageHelper.startPage(forum.getPageNum(), forum.getPageSize());
        List<DatingForum> memberList = datingMapper.getMyForumList(MemberUtil.getUserId());
        return ResponsePage.restPage(new PageInfo<>(memberList));

    }

    @Override
    public void editForum(DatingForum forum) {
        datingMapper.editForum(forum);
    }

    @Override
    public void like(Integer id) {
        Integer userId = MemberUtil.getUserId();
        Integer likeId = datingMapper.checkIsLicked(id, userId);
        if (likeId != null) {
            datingMapper.cancelLike(likeId);
        } else {
            datingMapper.addLike(id);
            datingMapper.like(userId, id);
        }
    }

    @Override
    public DatingForumDto getForumDetail(Integer id) {
        datingMapper.addView(id);
        return datingMapper.getForumDetail(id);
    }

    @Override
    public ResponsePage<DatingForum> getMyLike(DatingForumParam forum) {
        PageHelper.startPage(forum.getPageNum(), forum.getPageSize());
        List<DatingForum> memberList = datingMapper.getMyLike(MemberUtil.getUserId());
        return ResponsePage.restPage(new PageInfo<>(memberList));
    }

    @Override
    public void follow(Integer userId) {
        UmsMember userInfo = MemberUtil.getUserInfo();
        UmsMember followUser = userMapper.getUserInfo(userId);

        DatingFollow datingFollowA = new DatingFollow();
        DatingFollow datingFollowB = new DatingFollow();

        datingFollowA.setUserId(userInfo.getId());
        datingFollowB.setUserId(followUser.getId());

        datingFollowA.setFollowId(followUser.getId());
        datingFollowB.setFollowId(userInfo.getId());

        datingFollowA.setFollowUsername(followUser.getNickName());
        datingFollowB.setFollowUsername(userInfo.getNickName());

        datingFollowA.setFollowCover(followUser.getIcon());
        datingFollowB.setFollowCover(userInfo.getIcon());

        datingMapper.follow(datingFollowA);
        datingMapper.follow(datingFollowB);

    }

    @Override
    public ResponsePage<DatingFollow> getFollowList(DatingForumParam forum) {
        PageHelper.startPage(forum.getPageNum(), forum.getPageSize());
        List<DatingFollow> follows = datingMapper.getFollowList(MemberUtil.getUserId());
        return ResponsePage.restPage(new PageInfo<>(follows));

    }

    @Override
    public List<DatingMessage> getMessageList() {
        return datingMapper.getMessageList(MemberUtil.getUserId());
    }

    @Override
    public void addComment(DatingComments comments) {
        UmsMember userInfo = MemberUtil.getUserInfo();
        comments.setUserId(userInfo.getId());
        comments.setAvatar(userInfo.getIcon());
        comments.setUsername(userInfo.getNickName());
        datingMapper.addComment(comments);
    }

    @Override
    public void deleteComment(DatingComments comments) {
        Integer id = comments.getId();
        datingMapper.deleteComment(id);
    }

    @Override
    public void chat(DatingChat chat) {
        UmsMember userInfo = MemberUtil.getUserInfo();
        chat.setUserCover(userInfo.getIcon());
        chat.setUsername(userInfo.getUsername());
        chat.setUserId(userInfo.getId());
        chat.setMessage(replaceSwearWords(chat.getMessage()));
        datingMapper.chat(chat);
        notification(chat.getChatUserId());
    }

    @Override
    public List<DatingChat> chatList(Integer chatUserId) {
        // 获取两个聊天列表
        List<DatingChat> chatList1 = datingMapper.chatList1(chatUserId, MemberUtil.getUserId());
        List<DatingChat> chatList2 = datingMapper.chatList2(chatUserId, MemberUtil.getUserId());
        // 合并两个列表
        List<DatingChat> allChats = new ArrayList<>();
        allChats.addAll(chatList1);
        allChats.addAll(chatList2);
        // 根据 createTime 倒序排序
        allChats.sort((chat1, chat2) -> chat2.getCreateTime().compareTo(chat1.getCreateTime()));
        return allChats;
    }

    @Override
    public void addSwearing(String word) {
        datingMapper.addSwearing(word);
    }

    @Override
    public void deleteSwearing(Integer id) {
        datingMapper.deleteSwearing(id);

    }

    @Override
    public ResponsePage<DatingSwearing> swearingList(DatingEventParam param) {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<DatingSwearing> list = datingMapper.swearingList();
        return ResponsePage.restPage(new PageInfo<>(list));
    }

    @Override
    public List<DatingCommentsDto> getForumComment(DatingComments comments) {
        List<DatingCommentsDto> forumComment = datingMapper.getForumComment(comments);
        List<DatingCommentsDto> father = new ArrayList<>();
        List<DatingCommentsDto> son = new ArrayList<>();
        for (DatingCommentsDto dto : forumComment) {
            switch (dto.getLevel()) {
                case 1:
                    father.add(dto);
                    break;
                case 2:
                    son.add(dto);
                    break;
            }
        }
        for (DatingCommentsDto fatherComment : father) {
            List<DatingCommentsDto> sonList = new ArrayList<>();
            for (DatingCommentsDto sonInfo : son) {
                if (sonInfo.getCommentId().equals(fatherComment.getId())) {
                    sonList.add(sonInfo);
                }
            }
            fatherComment.setChildComment(sonList);
        }
        return father;
    }

    /**
     * 替换消息中的脏话
     */
    private String replaceSwearWords(String message) {
        for (String swearWord : swearWordsSet) {
            // 使用正则表达式来匹配脏话，去掉单词边界
            String regex = Pattern.quote(swearWord);
            Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(message);

            // 动态替换脏话为星号，星号数量和脏话长度相同
            while (matcher.find()) {
                String replacement = generateStars(matcher.group().length());  // 动态生成与脏话相同长度的星号
                message = matcher.replaceAll(replacement);
            }
        }
        return message;
    }

    // 辅助方法：生成指定长度的星号字符串
    private String generateStars(int length) {
        StringBuilder stars = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            stars.append('*');
        }
        return stars.toString();
    }
}
